package com.ruoyi.web.controller.trackApply;


import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ExecUtil;
import com.ruoyi.common.utils.bean.ObjUtil;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.dj.mapper.TerrMagnetismMapper;
import com.ruoyi.common.utils.biz.BizModule;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.web.server.entity.ResultSave;
import com.ruoyi.web.server.service.ResultSaveService;
import com.ruoyi.web.vo.LowOrbitSpaceVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 *  低轨航天器指数预报
 * </p>
 *
 * @author liuhl
 * @since 2024-05-15
 */
@RestController
@RequestMapping("/lowOrbit")
@AllArgsConstructor
@Slf4j
@Api(tags = "低轨航天器指数预报")
public class LowOrbitSpaceController {

    private TerrMagnetismMapper queryMapper;
    private ResultSaveService resultSaveService;


    @PostMapping("/solar")
    @ApiOperation(value = "太阳辐射指数预报", notes = "根据预报产品和时间得出预报结果", httpMethod = "POST")
    public AjaxResult solarPredict(@RequestBody LowOrbitSpaceVo vo) {
        String codePath = PathUtil.codeModuleDir(BizModule.TRACK_APPLY)  + PathUtil.moduleDirs().getTrackApply().get("solarPredict");
        String command = "python "+codePath+" "+vo.getIndex()+" "+vo.getTime();
        String results = ExecUtil.execCmdWithResult(command);
        Map<String,Object> resultMap = JSONUtil.toBean(results, Map.class);

        String resultData = resultMap.get("path").toString();

        List<String> fileNameList = JSONUtil
                .parseArray(resultData)
                .toList(String.class)
                .stream()
                .map(filePath -> filePath.substring(filePath.lastIndexOf("/") + 1))
                .collect(Collectors.toList());
        String fileNames = JSONUtil.toJsonStr(fileNameList);

        ResultSave resultSave = ResultSave.builder()
                .params(ObjUtil.toStr(vo))
                .resultData(JSONUtil.toJsonStr(resultData))
                .fileNames(fileNames)
                .module(ResultSaveModule.TRACK_APPLY)
                .submodule(ResultSaveModule.TRACK_APPLY_LOW_SOLAR)
                .createTime(new Date())
                .build();

        resultSaveService.save(resultSave);

        resultMap.put("resultData", JSONUtil.toJsonStr(resultData));
        resultMap.put("module", ResultSaveModule.TRACK_APPLY);
        resultMap.put("submodule", ResultSaveModule.TRACK_APPLY_LOW_SOLAR);

        return AjaxResult.success(resultMap);
    }

    @PostMapping("/magnetic")
    @ApiOperation(value = "地磁指数预报", notes = "根据磁暴类型和时间得出预报结果", httpMethod = "POST")
    public AjaxResult magneticPredict(@RequestBody LowOrbitSpaceVo vo) {
        String codePath = PathUtil.codeModuleDir(BizModule.TRACK_APPLY)  + PathUtil.moduleDirs().getTrackApply().get("magneticPredict");
        String command = "python "+codePath+" "+vo.getTime();
        String results = ExecUtil.execCmdWithResult(command);
        Map<String,Object> resultMap = JSONUtil.toBean(results, Map.class);

        String resultData = resultMap.get("path").toString();

        List<String> fileNameList = JSONUtil.parseArray(resultData).toList(String.class)
                .stream()
                .map(filePath -> filePath.substring(filePath.lastIndexOf("/") + 1))
                .collect(Collectors.toList());
        String fileNames = JSONUtil.toJsonStr(fileNameList);

        ResultSave resultSave = ResultSave.builder()
                .params(ObjUtil.toStr(vo))
                .resultData(JSONUtil.toJsonStr(resultData))
                .fileNames(fileNames)
                .module(ResultSaveModule.TRACK_APPLY)
                .submodule(ResultSaveModule.TRACK_APPLY_LOW_MAG)
                .createTime(new Date())
                .build();
        resultSaveService.save(resultSave);

        resultMap.put("resultData", JSONUtil.toJsonStr(resultData));
        resultMap.put("module", ResultSaveModule.TRACK_APPLY);
        resultMap.put("submodule", ResultSaveModule.TRACK_APPLY_LOW_MAG);

        return AjaxResult.success(resultMap);
    }

    @GetMapping("/time")
    @ApiOperation(value = "获取可选日期", notes = "获取预报可选日期", httpMethod = "GET")
    public AjaxResult getTime(String type,String index) {

        // TODO 这一块要找纪英豪沟通
        // 地磁：
        //SWDATA_OBS_KP -- 比如界面可以选择2024年时，就意味着表里面的数据存在2023-12-31 22:15:00的数据, 界面能选择的最早年份先不考虑。
        //
        //太阳：
        //SWDATA_OBS_S107 -- 对应界面的S10.7， 比如界面可以选择2024-10时，就意味着表里面的数据存在2024-9月最后一天的数据, 界面能选择的最早年月先不考虑。
        //
        //这两个规则不一样，但是写一个接口吧：GET  /lowOrbit/time   地磁传 type=magnetic, 太阳传 type=solar，index=S107 响应是一个字符串："2024" 或者 "2024-10";

        String result = "";
        if ("magnetic".equals(type)){
            //比如 maxTime = 2023-01-01 22:15:00，则判断 2023-01-01 22:15:00 是不是 2023年最后一天，如果是则返回 2024，否则返回2023。
            String maxTime = queryMapper.getPredictTime("SWDATA_OBS_KP", null);
            //String maxTime = "2023-12-31 22:15:00";
            String[] split = maxTime.split(" ")[0].split("-");
            LocalDate dbDate = LocalDate.of(Integer.valueOf(split[0]), Integer.valueOf(split[1]), Integer.valueOf(split[2]));
            LocalDate lastDayOfYear = dbDate.with(TemporalAdjusters.lastDayOfYear());
            boolean equal = dbDate.isEqual(lastDayOfYear);
            if (equal){
                result = String.valueOf(Integer.valueOf(split[0]) + 1);
            }else {
                result = split[0];
            }
        }

        if ("solar".equals(type)){
            //比如 maxTime = 2024-05-05，则判断 2024-05-05是不是当月的最后一天，如果是，则返回 2024-06，否则返回2024-05。
            String maxTime = queryMapper.getPredictTime("SWDATA_OBS_"+index, null);
            String[] split = maxTime.split(" ")[0].split("-");
            LocalDate dbDate = LocalDate.of(Integer.valueOf(split[0]), Integer.valueOf(split[1]), Integer.valueOf(split[2]));
            LocalDate lastDayOfMonth = dbDate.with(TemporalAdjusters.lastDayOfMonth());
            boolean equal = dbDate.isEqual(lastDayOfMonth);
            if (equal){
                result = split[0] + "-" +(Integer.valueOf(split[1]) + 1);
            }else {
                result = split[0] + "-" +split[1];
            }
        }
        return AjaxResult.success(result);
    }


}
